package com.example.demo1.generator.codedesign.api;

import com.example.demo1.generator.codedesign.ResponseBuilder;
import com.example.demo1.generator.codedesign.WebConstant;
import com.example.demo1.generator.codedesign.model.Table;
import com.example.demo1.generator.codedesign.service.SchemaService;
import com.example.demo1.generator.codedesign.service.TemplateService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipOutputStream;

@RestController
@RequestMapping(CodeDesignApi.PATH)
public class CodeDesignApi {

	public final static String PATH = "/codedesign";

	@Resource
	private SchemaService schemaService;

	@Resource
	private TemplateService templateService;

	Map<String, Table> tableCache = new HashMap<>();

	@Autowired
	private WebConstant webConstant;
	
	@RequestMapping("tables")
	public String tables() throws Exception {
		Map<String, Object> result = new HashMap<>();

		tableCache.clear();
		List<Table> tables = schemaService.getTables();
		for (Table item : tables) {
			tableCache.put(item.getName(), item);
		}

		result.put("items", tableCache.values());
		return ResponseBuilder.ok(result);
	}

	@RequestMapping("previewCode")
	public String previewCode(@RequestBody Table formTable,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		String moduleName = formTable.getModuleName();
		String tableName = formTable.getName();
		Assert.notNull(moduleName, "error.empty");
		Map<String, Object> result = new HashMap<>();

		Table cacheTable = tableCache.get(tableName);
		if (cacheTable != null) {
			moduleName = StringUtils.lowerCase(moduleName);
			String requestPath = "/" + moduleName + "/"
					+ StringUtils.lowerCase(cacheTable.getClassName());

			cacheTable.setPackageName("com.example.demo1");
			cacheTable.setModuleName(moduleName);
			cacheTable.setRequestPath(requestPath);
			
			result.put("templates", templateService.build(cacheTable));
			return ResponseBuilder.ok(result);

		} else {
			return ResponseBuilder.ok();
		}

	}
	

	public static void saveFile(byte[] file, String filePath, String fileName) throws Exception {
		filePath = "E:\\liangxin\\file\\";
        File fileDir = new File(filePath);
        if (!fileDir.exists()) { // 如果不存在 则创建
            fileDir.mkdirs();
        }
		URLEncoder.encode(fileName, "utf-8");
		FileOutputStream out = new FileOutputStream(filePath + fileName);
		out.write(file);
		out.flush();
		out.close();
	}

	
	@RequestMapping("exportCode")
	public void exportCode(@RequestBody Table formTable,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		String moduleName = formTable.getModuleName();
		String tableName = formTable.getName();
		Assert.notNull(moduleName, "error.empty");

		Table cacheTable = tableCache.get(tableName);
		if (cacheTable != null) {
			moduleName = StringUtils.lowerCase(moduleName);
			String requestPath = "/" + moduleName + "/"
					+ StringUtils.lowerCase(cacheTable.getClassName());

			cacheTable.setPackageName("com.example.demo1");
			cacheTable.setModuleName(moduleName);
			cacheTable.setRequestPath(requestPath);

			
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			ZipOutputStream zip = new ZipOutputStream(outputStream);
			/*for(String table : formTable){			
				//生成代码
				templateService.build(cacheTable,zip);
			}*/
			templateService.build(cacheTable,zip);
			IOUtils.closeQuietly(zip);			
			byte[] data = outputStream.toByteArray();
			SimpleDateFormat sdf = new SimpleDateFormat("MMddHHmm");
			String date = sdf.format(new Date());
			String filePath = webConstant.DEFAULT_EXPORT_CODE;
			saveFile(data, filePath, date+"_lx.zip");
			response.reset();
			response.setHeader("Content-Disposition", "attachment; filename=\""+date+"_ts.zip\"");
			response.addHeader("Content-Length", "" + data.length);
			response.setContentType("application/octet-stream; charset=UTF-8");
			IOUtils.write(data, response.getOutputStream());
		} 

	}
	
	
	@RequestMapping("exportsCode")
	public void exportsCode(@RequestBody List<Table> sTables,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		ZipOutputStream zip = new ZipOutputStream(outputStream);
		for(Table formTable : sTables){			
			String moduleName = formTable.getModuleName();
			String tableName = formTable.getName();
			Assert.notNull(moduleName, "error.empty");

			Table cacheTable = tableCache.get(tableName);
			if (cacheTable != null) {
				moduleName = StringUtils.lowerCase(moduleName);
				String requestPath = "/" + moduleName + "/"
						+ StringUtils.lowerCase(cacheTable.getClassName());

				cacheTable.setPackageName("com.example.demo1");
				cacheTable.setModuleName(moduleName);
				cacheTable.setRequestPath(requestPath);	
				templateService.build(cacheTable,zip);				
			} 
		}
		
		IOUtils.closeQuietly(zip);			
		byte[] data = outputStream.toByteArray();
		SimpleDateFormat sdf = new SimpleDateFormat("MMddHHmm");
		String date = sdf.format(new Date());
		String filePath = webConstant.DEFAULT_EXPORT_CODE;
		saveFile(data, filePath, date+"_lx.zip");
		response.reset();
		response.setHeader("Content-Disposition", "attachment; filename=\""+date+"_ts.zip\"");
		response.addHeader("Content-Length", "" + data.length);
		response.setContentType("application/octet-stream; charset=UTF-8");
		IOUtils.write(data, response.getOutputStream());
		

	}
}
